﻿#include "checksystem.h"
#include "ui_checksystem.h"

#include <QTime>

ModelSetting CheckSystem::FDsetting=ModelSetting("G:/APP1/OpenCV/SeetaFace/bin/model/fd_2_00.dat",ModelSetting::CPU, 0);
ModelSetting CheckSystem::FLMsetting=ModelSetting("G:/APP1/OpenCV/SeetaFace/bin/model/pd_2_00_pts5.dat",ModelSetting::CPU, 0);
ModelSetting CheckSystem::FDBsetting=ModelSetting("G:/APP1/OpenCV/SeetaFace/bin/model/fr_2_10.dat",ModelSetting::CPU, 0);

CheckSystem::CheckSystem(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::CheckSystem),
      engine(FDsetting, FLMsetting, FDBsetting),
      faceTracker(FDsetting)
{
    ui->setupUi(this);
    this->login = false;
    //打开摄像头
    capture.open(0);
    //开启定时器
    timerid = startTimer(100);
    this->FDPtr = &engine.FD;
    this->FLDPtr = &engine.PD;
    this->FDPtr->set(seeta::FaceDetector::PROPERTY_MIN_FACE_SIZE,80);
    //导出数据库
    engine.Load("F:/yueqian/sql/db/project/face.fdb");
    //开启定时器
    startTimer(100);
    //初始化模型
    model = new QSqlTableModel();//默认数据库
    model->setTable("Personnel_information");//绑定数据库中对应表格
    //初始化
    cheeck_Bt = false;
    table_name = QDateTime::currentDateTime().toString("yyyyMMdd");
}

CheckSystem::~CheckSystem()
{
    delete ui;
}

//登录
void CheckSystem::on_pushButton_clicked()
{
    if ( !this->login ){
        //空白对话框
        QDialog dialog(this);
        dialog.resize(this->size());
        //在对话框添加组件
        QLabel text(&dialog);
        text.setStyleSheet("font: 24pt 宋体");
        text.setText("欢迎使用人脸签到系统，请登录！");
        text.setGeometry(200,0,500,50);
        QLineEdit endi01(&dialog);
        endi01.setPlaceholderText("账号：");
        endi01.setGeometry(250,150,300,50);
        QLineEdit endi02(&dialog);
        endi02.setPlaceholderText("密码：");
        endi02.setGeometry(250,250,300,50);
        QPushButton button(&dialog);
        button.setGeometry(250,350,100,50);
        button.setText("登录");
        QPushButton button2(&dialog);
        button2.setGeometry(450,350,100,50);
        button2.setText("退出");
        dialog.setStyleSheet("QPushButton{font: 12pt 宋体;color: rgb(128, 64, 255);background-color: rgb(255, 255, 255);"
                             "border:1px solid#ffffff;border-radius:5px;}"
                             "QPushButton:hover{ color: rgb(255, 38, 103);background-color: rgb(255, 255, 255);"
                             "border:1px solid#ffffff; border-radius:5px;}"
                             "QPushButton:pressed{ color: rgb(128, 64, 255);background-color: rgb(225, 188, 255);"
                             "border:1px solid#ffbcff; border-radius:5px;}");

        //把按钮的点击信号关联对话框退出的槽函数
        connect(&button, &QPushButton::clicked, &dialog, [&]()->void{
                    if (endi01.text() == "123" && endi02.text() == "123"){
                        this->login = true;
                        QMessageBox::warning(this,"提示","登录成功！");
                        dialog.accept();
                    }else{
                        QMessageBox::warning(this,"提示","账号或者密码输入错误，请重新输入！");
                    }
                });
        //把按钮的点击信号关联对话框退出的槽函数
        connect(&button2, &QPushButton::clicked, &dialog, &QDialog::accept);
        dialog.exec();
    }else{
        int ret=QMessageBox::information(this,"提示", "已成功登录，是否要选择退出！", QMessageBox::Yes, QMessageBox::No);
        if(ret == QMessageBox::Yes)
        {
            this->login = false;
            QMessageBox::warning(this,"提示","成功退出登录！");
        }
        if(ret == QMessageBox::No)
        {

        }
    }
}
//设置
void CheckSystem::on_pushButton_3_clicked()
{
    if (!this->login){
        QMessageBox::warning(this,"提示","请先进行登录！");
    }else{

    }
}
//查找
bool CheckSystem::select_user(int row){
    model->setTable("Personnel_information");//绑定数据库中对应表格
    model->select();
    if (model->rowCount() == 0)
        return false;
    QString Number = model->record(row).value(0).toString();
    QString Full_name = model->record(row).value(1).toString();
    QString Time = QDateTime::currentDateTime().toString("hh:mm:ss");
    QString Photo = QDateTime::currentDateTime().toString("yyyyMMdd_hh:mm:sszzz");

    //保存到签到表中
    model->setTable(table_name);//绑定数据库中对应表格
    //创建一条记录
    QSqlRecord record = model->record();
    //初始化
    record.setValue("Number",Number);
    record.setValue("Full_name",Full_name);
    record.setValue("Time",Time);
    record.setValue("Photo",Photo);
    if (!model->insertRecord(0,record))
    {
        qDebug() << "插入失败";
        QMessageBox::information(this,"失败","不能重符签到!");
        cheeck_Bt = false;
        return false;
    }
    ui->Number->setText(Number);
    ui->Full_name->setText(Full_name);
    ui->Time->setText(Time);
    ui->State->setText("签到成功");
    model->select();
    ui->success->setText(QString::number(model->rowCount()));
    cheeck_Bt = false;
    return true;
}
//seeta来识别人脸
void CheckSystem::cheeck_Seeta(){
    Mat videoImage ;
    capture.read(videoImage);
    if(videoImage.data == nullptr) return ;
    SeetaImageData image;  //<<===videoImage
    image.width = videoImage.cols;
    image.height = videoImage.rows;
    image.channels = videoImage.channels();
    image.data  =videoImage.data;
    //追踪
    SeetaTrackingFaceInfoArray  faceArray = faceTracker.track(image);
    for(int i=0; i<faceArray.size; i++)
    {
        SeetaTrackingFaceInfo faceInfo = faceArray.data[i];
        cv::Rect rect = {faceInfo.pos.x, faceInfo.pos.y, faceInfo.pos.width, faceInfo.pos.height};
        rectangle(videoImage,rect, Scalar(0,0,255));
        if (!cheeck_Bt) continue;
        //获取人脸5个特征点
        std::vector<SeetaPointF> points = engine.DetectPoints(image, faceInfo.pos);
        static int pid = -1;
        if(faceInfo.PID != pid)
        {
            //识别
            int64_t index = -1;
            float similarity = 0.0;
            int id  = engine.QueryTop(image, points.data(), 1, &index, &similarity);
            qDebug()<<id<<similarity<<index;
            pid = faceInfo.PID;
            if (similarity > 0.5){
                select_user(index);
            }
        }
    }
    //在Qt显示图片
    QImage imageq(videoImage.data, videoImage.cols, videoImage.rows, videoImage.step, QImage::Format_BGR888);
    QPixmap mmp = QPixmap::fromImage(imageq);
    ui->pix->setPixmap(mmp);
}
//定时器
void CheckSystem::timerEvent(QTimerEvent *event){
    cheeck_Seeta();
}
//签到
void CheckSystem::on_pushButton_2_clicked()
{
    cheeck_Bt = !cheeck_Bt;
}
